#if 0



#include <osgParticle/Particle>
#include <osgParticle/ParticleSystem>
#include <osgParticle/ParticleSystemUpdater>
#include <osgParticle/ModularEmitter>
#include <osgParticle/ModularProgram>
#include <osgParticle/RandomRateCounter>
#include <osgParticle/SectorPlacer>
#include <osgParticle/RadialShooter>
#include <osgParticle/AccelOperator>
#include <osgParticle/FluidFrictionOperator>
#include <osg/ArgumentParser>
#include <model/root.h>
#include <model/particletemplate.h>
#include <player/controller.h>
#include <player/particlesystem.h>
#include <osgViewer/Viewer>
#include <osg/Group>
#include <osg/Geode>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMessageBox>

#include "model/emittertemplate.h"
#include "model/particleshooter.h"

void build_particle_world(osg::Group *root);

using namespace model;

static ParticleTemplate *pt0=0,*pt1=0;
static EmitterTemplate *et0=0;
static QPointer<Root> root;

void build_root()
{
   ParticleTemplate::ColorControlPoint ccp;
   ParticleTemplate::FloatControlPoint acp;
   ParticleTemplate::TimeMark tm;

   root=new Root;

   pt0=new ParticleTemplate;
   pt0->set_life_time(RandomDouble(4));
   pt0->set_visible(true);
   pt0->set_density(1);
   pt0->set_texture_file("/home/b/Work/fireworkcreator/test1.png");
   pt0->set_friction_enabled(true);
   pt0->set_gravitation_enabled(true);
   pt0->set_num_tiles(2);
   pt0->set_shape(ParticleTemplate::shape_quad);
   pt0->set_tile(2,1);
   pt0->set_tile_speed_mode(ParticleTemplate::tile_speed_relative);
   ccp.color=RandomColor(osg::Vec4(1,0,0,1));
   pt0->color_control_points.append(ccp);
   acp.value=RandomDouble(1);
   pt0->alpha_control_points.append(acp);
   acp.value=RandomDouble(1);
   pt0->size_control_points.append(acp);
   acp.value=RandomDouble(1);
   pt0->radius_control_points.append(acp);
   root->particle_templates.insert(pt0);

   et0=new EmitterTemplate;
   EmitterTemplate::EmitterBlock eb;
   eb.amount=11;
   eb.angle=RandomPosition(osg::Vec3(0,0,0));
   eb.angular_velocity=RandomPosition(osg::Vec3(0,0,0));
   eb.emitter=0;
   eb.particle=pt0;
   eb.position=RandomPosition(osg::Vec3(-7,-7,0),osg::Vec3(7,7,16));
   eb.scale=1;
   eb.synchronized=false;
   et0->emitter_blocks.append(eb);
   root->emitter_templates.insert(et0);

   pt1=new ParticleTemplate;
   pt1->set_life_time(RandomDouble(3));
   pt1->set_visible(true);
   pt1->set_density(10);
   pt1->set_texture_file("/home/b/Work/fireworkcreator/test1.png");
   pt1->set_friction_enabled(true);
   pt1->set_gravitation_enabled(true);
   pt1->set_num_tiles(4);
   pt1->set_shape(ParticleTemplate::shape_quad);
   pt1->set_tile(2,1);
   pt1->set_tile_speed_mode(ParticleTemplate::tile_speed_absolute);
   tm.mode=ParticleTemplate::TimeMark::from_start;
   tm.time=RandomDouble(2);
   pt1->time_marks.insert("t0",tm);
   tm.mode=ParticleTemplate::TimeMark::from_other;
   tm.time=RandomDouble(1);
   tm.other="t0";
   pt1->time_marks.insert("t1",tm);
   tm.mode=ParticleTemplate::TimeMark::from_end;
   tm.time=RandomDouble(0);
   tm.other="";
   pt1->time_marks.insert("end",tm);
   ccp.color=RandomColor(osg::Vec4(0,1,0,1));
   pt1->color_control_points.append(ccp);
   ccp.color=RandomColor(osg::Vec4(0,0,1,1));
   ccp.time="t1";
   pt1->color_control_points.append(ccp);
   ccp.color=RandomColor(osg::Vec4(0,1,0,1));
   ccp.time="";
   pt1->color_control_points.append(ccp);
   acp.value=RandomDouble(1);
   pt1->alpha_control_points.append(acp);
   acp.time="t0";
   acp.value=RandomDouble(0);
   pt1->alpha_control_points.append(acp);
   acp.time="t1";
   acp.value=RandomDouble(1);
   pt1->alpha_control_points.append(acp);
   acp.time="";
   acp.value=RandomDouble(0);
   pt1->alpha_control_points.append(acp);
   acp.value=RandomDouble(0.5);
   pt1->size_control_points.append(acp);
   acp.value=RandomDouble(1);
   pt1->radius_control_points.append(acp);
   ParticleTemplate::EmitterBlock peb;
   peb.emitter=et0;
   peb.time1="end";
   pt1->emitters.append(peb);
   peb.emitter=et0;
   peb.time1="t0";
   peb.time2="end";
   peb.interval_min=0.02;
   peb.interval_max=0.3;
   //pt1->emitters.append(peb);
   root->particle_templates.insert(pt1);

   model::ParticleShooter* shooter=new model::ParticleShooter;
   shooter->set_time(1.7);
   shooter->set_position(osg::Vec3(0,0,0));
   shooter->set_angle(osg::Vec3(0,0,0));
   shooter->set_velocity(osg::Vec3(10,10,10));
   shooter->set_angular_velocity(osg::Vec3(0,0,0));
   shooter->set_particle_template(pt0);
   root->shooters.insert(shooter);
   shooter=new model::ParticleShooter;
   shooter->set_time(2.70);
   shooter->set_position(osg::Vec3(10,0,0));
   shooter->set_angle(osg::Vec3(0,0,0));
   shooter->set_velocity(osg::Vec3(0,0,20));
   shooter->set_angular_velocity(osg::Vec3(0,0,0));
   shooter->set_particle_template(pt1);
   root->shooters.insert(shooter);
   //QMessageBox::information(0,"debug info","shooters created");
}

extern QMainWindow* create_test_window(osg::Group*);

void test()
{
   using namespace player;

   if(root)
      return;

   /*Root* droot=build_root();
   droot->delete_contents();
   delete droot;*/
    //osgViewer::Viewer viewer;
   build_root();

   osg::Group* group = new osg::Group;
   //QMessageBox::information(0,"debug info","creating controller");
   Controller* controller=new Controller(root);
   //QMessageBox::information(0,"debug info","controller created");
   osg::Geode* geode=new osg::Geode;
   controller->add_particle_systems(geode);
   group->addChild(geode);
   group->addChild(controller);

   /*ParticleSystem* ps0=controller->particle_system_for_template(pt0);
   ParticleSystem* ps1=controller->particle_system_for_template(pt1);
   ParticleParam pp;

   controller->start();
   pp.position=osg::Vec3(0,0,0);
   pp.angle=osg::Vec3(0,0,0);
   pp.velocity=osg::Vec3(10,10,10);
   pp.angular_velocity=osg::Vec3(0,0,0);
   pp.time=0;
   ps0->schedule_create(pp);
   pp.velocity=osg::Vec3(0,0,20);
   pp.position=osg::Vec3(10,0,0);
   ps1->schedule_create(pp);*/

   //viewer.setSceneData(group);
   //int ret=viewer.run();
   // Use QGLWidget and integrate OSG with it by adapting osgViewer via its embedded window mode
   QMainWindow* mw=create_test_window(group);
   root->setParent(mw);

    /*osgViewer::Viewer viewer;
    osg::Group *root = new osg::Group;
    build_particle_world(root);
    viewer.setSceneData(root);
    return viewer.run();*/
}


////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// SIMPLE PARTICLE SYSTEM CREATION
//////////////////////////////////////////////////////////////////////////////

osgParticle::ParticleSystem *create_simple_particle_system(osg::Group *root)
{

    // Ok folks, this is the first particle system we build; it will be
    // very simple, with no textures and no special effects, just default
    // values except for a couple of attributes.

    // First of all, we create the ParticleSystem object; it will hold
    // our particles and expose the interface for managing them; this object
    // is a Drawable, so we'll have to add it to a Geode later.

    osgParticle::ParticleSystem *ps = new osgParticle::ParticleSystem;

    // As for other Drawable classes, the aspect of graphical elements of
    // ParticleSystem (the particles) depends on the StateAttribute's we
    // give it. The ParticleSystem class has an helper function that let
    // us specify a set of the most common attributes: setDefaultAttributes().
    // This method can accept up to three parameters; the first is a texture
    // name (std::string), which can be empty to disable texturing, the second
    // sets whether particles have to be "emissive" (additive blending) or not;
    // the third parameter enables or disables lighting.

    ps->setDefaultAttributes("", true, false);

    // Now that our particle system is set we have to create an emitter, that is
    // an object (actually a Node descendant) that generate new particles at
    // each frame. The best choice is to use a ModularEmitter, which allow us to
    // achieve a wide variety of emitting styles by composing the emitter using
    // three objects: a "counter", a "placer" and a "shooter". The counter must
    // tell the ModularEmitter how many particles it has to create for the
    // current frame; then, the ModularEmitter creates these particles, and for
    // each new particle it instructs the placer and the shooter to set its
    // position vector and its velocity vector, respectively.
    // By default, a ModularEmitter object initializes itself with a counter of
    // type RandomRateCounter, a placer of type PointPlacer and a shooter of
    // type RadialShooter (see documentation for details). We are going to leave
    // these default objects there, but we'll modify the counter so that it
    // counts faster (more particles are emitted at each frame).

    osgParticle::ModularEmitter *emitter = new osgParticle::ModularEmitter;

    // the first thing you *MUST* do after creating an emitter is to set the
    // destination particle system, otherwise it won't know where to create
    // new particles.

    emitter->setParticleSystem(ps);

    // Ok, get a pointer to the emitter's Counter object. We could also
    // create a new RandomRateCounter object and assign it to the emitter,
    // but since the default counter is already a RandomRateCounter, we
    // just get a pointer to it and change a value.

    osgParticle::RandomRateCounter *rrc =
        static_cast<osgParticle::RandomRateCounter *>(emitter->getCounter());

    // Now set the rate range to a better value. The actual rate at each frame
    // will be chosen randomly within that range.

    rrc->setRateRange(20, 30);    // generate 20 to 30 particles per second

    // The emitter is done! Let's add it to the scene graph. The cool thing is
    // that any emitter node will take into account the accumulated local-to-world
    // matrix, so you can attach an emitter to a transform node and see it move.

    root->addChild(emitter);

    // Ok folks, we have almost finished. We don't add any particle modifier
    // here (see ModularProgram and Operator classes), so all we still need is
    // to create a Geode and add the particle system to it, so it can be
    // displayed.

    osg::Geode *geode = new osg::Geode;
    geode->addDrawable(ps);

    // add the geode to the scene graph
    root->addChild(geode);

    return ps;

}

//////////////////////////////////////////////////////////////////////////////
// MAIN SCENE GRAPH BUILDING FUNCTION
//////////////////////////////////////////////////////////////////////////////

void build_particle_world(osg::Group *root)
{

    // In this function we are going to create two particle systems;
    // the first one will be very simple, based mostly on default properties;
    // the second one will be a little bit more complex, showing how to
    // create custom operators.
    // To avoid inserting too much code in a single function, we have
    // splitted the work into two functions which accept a Group node as
    // parameter, and return a pointer to the particle system they created.

    osgParticle::ParticleSystem *ps1 = create_simple_particle_system(root);

    // Now that the particle systems and all other related objects have been
    // created, we have to add an "updater" node to the scene graph. This node
    // will react to cull traversal by updating the specified particles system.

    osgParticle::ParticleSystemUpdater *psu = new osgParticle::ParticleSystemUpdater;
    psu->addParticleSystem(ps1);

    // add the updater node to the scene graph
    root->addChild(psu);
}

/*
int scene()
{
   osg::Group* root = new osg::Group();
   osg::Geode* pyramidGeode = new osg::Geode();
   osg::Geometry* pyramidGeometry = new osg::Geometry();

   pyramidGeode->addDrawable(pyramidGeometry);
   root->addChild(pyramidGeode);

   osg::Vec3Array* pyramidVertices = new osg::Vec3Array;
   pyramidVertices->push_back( osg::Vec3( 0, 0, 0) ); // front left
   pyramidVertices->push_back( osg::Vec3(10, 0, 0) ); // front right
   pyramidVertices->push_back( osg::Vec3(10,10, 0) ); // back right
   pyramidVertices->push_back( osg::Vec3( 0,10, 0) ); // back left
   pyramidVertices->push_back( osg::Vec3( 5, 5,10) ); // peak

   pyramidGeometry->setVertexArray( pyramidVertices );

   osg::DrawElementsUInt* pyramidBase =
      new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
   pyramidBase->push_back(3);
   pyramidBase->push_back(2);
   pyramidBase->push_back(1);
   pyramidBase->push_back(0);
   pyramidGeometry->addPrimitiveSet(pyramidBase);
  osg::DrawElementsUInt* pyramidFaceOne =
      new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
   pyramidFaceOne->push_back(0);
   pyramidFaceOne->push_back(1);
   pyramidFaceOne->push_back(4);
   pyramidGeometry->addPrimitiveSet(pyramidFaceOne);
   osg::DrawElementsUInt* pyramidFaceTwo =
      new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
   pyramidFaceTwo->push_back(1);
   pyramidFaceTwo->push_back(2);
   pyramidFaceTwo->push_back(4);
   pyramidGeometry->addPrimitiveSet(pyramidFaceTwo);
   osg::DrawElementsUInt* pyramidFaceThree =
      new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
   pyramidFaceThree->push_back(2);
   pyramidFaceThree->push_back(3);
   pyramidFaceThree->push_back(4);
   pyramidGeometry->addPrimitiveSet(pyramidFaceThree);
   osg::DrawElementsUInt* pyramidFaceFour =
      new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
   pyramidFaceFour->push_back(3);
   pyramidFaceFour->push_back(0);
   pyramidFaceFour->push_back(4);
   pyramidGeometry->addPrimitiveSet(pyramidFaceFour);

   osg::Vec4Array* colors = new osg::Vec4Array;
   colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) ); //index 0 red
   colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f) ); //index 1 green
   colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f) ); //index 2 blue
   colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f) ); //index 3 white
   colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) ); //index 4 red

   pyramidGeometry->setColorArray(colors);
   pyramidGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

// Declare and initialize a transform node.
   osg::PositionAttitudeTransform* pyramidTwoXForm =
      new osg::PositionAttitudeTransform();

// Use the 'addChild' method of the osg::Group class to
// add the transform as a child of the root node and the
// pyramid node as a child of the transform.
   root->addChild(pyramidTwoXForm);
   pyramidTwoXForm->addChild(pyramidGeode);

// Declare and initialize a Vec3 instance to change the
// position of the tank model in the scene
   osg::Vec3 pyramidTwoPosition(15,0,0);
   pyramidTwoXForm->setPosition( pyramidTwoPosition );

   osgViewer::Viewer viewer;
   viewer.setSceneData( root );
   viewer.run();
}
*/


#endif